package yartiss.engine.simulation.system.schedulable;

import java.util.ArrayList;
import java.util.Map;

import yartiss.engine.simulation.IEnergyConsumptionProfile;
import yartiss.engine.simulation.energy.profiles.consumption.ConsumptionProfileFactory;
import yartiss.engine.simulation.system.ITask;

public class SchedulableFactory { 

	public static String[] availableTypes = new String[] { "simple", "graph",
			"subtask" };

	public static ITask newInstance(Map<String, Object> params) {
		ITask task = null;
		long firstRelease;
		long wcet;
		long wcee;
		long period;
		long deadline;
		int priority;
		int nbProc;
		IEnergyConsumptionProfile ecp;

		String type = params.get("type").toString().toLowerCase();
		
		if("simple".equals(type)){
			firstRelease = Long
					.parseLong(params.get("firstrelease").toString());
			wcet = Long.parseLong(params.get("wcet").toString());
			wcee = Long.parseLong(params.get("wcee").toString());
			period = Long.parseLong(params.get("period").toString());
			deadline = Long.parseLong(params.get("deadline").toString());
			priority = Integer.parseInt(params.get("priority").toString());
			ecp = params.containsKey("constype") ? ConsumptionProfileFactory
					.newIntance(params.get("constype").toString())
					: ConsumptionProfileFactory.newIntance("default");
			task = new SimpleTask(firstRelease, wcet, wcee, period, deadline,
					priority, ecp);
			}
		else if("graph".equals(type)){
			firstRelease = Long
					.parseLong(params.get("firstrelease").toString());
			period = Long.parseLong(params.get("period").toString());
			deadline = Long.parseLong(params.get("deadline").toString());
			priority = Integer.parseInt(params.get("priority").toString());
			@SuppressWarnings("unchecked")
			ArrayList<SubTask> subtasks = (ArrayList<SubTask>) params
					.get("tasks");
			ecp = params.containsKey("constype") ? ConsumptionProfileFactory
					.newIntance(params.get("constype").toString())
					: ConsumptionProfileFactory.newIntance("default");
			wcee = 0;
			ecp = ConsumptionProfileFactory.newIntance("default");
			task = new GraphTask(firstRelease, wcee, period, deadline,
					priority, subtasks, ecp);
			}
		else if("subtask".equals(type)){
			firstRelease = Long
					.parseLong(params.get("firstrelease").toString());
			wcet = Long.parseLong(params.get("wcet").toString());
			wcee = Long.parseLong(params.get("wcee").toString());
			period = Long.parseLong(params.get("period").toString());
			deadline = Long.parseLong(params.get("deadline").toString());
			priority = Integer.parseInt(params.get("priority").toString());
			nbProc = Integer.parseInt(params.get("nbproc").toString());
			ecp = params.containsKey("constype") ? ConsumptionProfileFactory
					.newIntance(params.get("constype").toString())
					: ConsumptionProfileFactory.newIntance("default");
			wcee = 0;
			ecp = ConsumptionProfileFactory.newIntance("default");
			task = new SubTask(firstRelease, wcet, wcee, period, deadline,
					priority, nbProc, ecp);
			}

		else 
			throw new IllegalArgumentException("Task model ("
					+ params.get("type") + ") doesn't exist...");
		return task;
	}

	public static ITask newInstance(Object... params) {
		ITask iTask = null;

		long firstRelease;
		long wcet;
		long wcee;
		long period;
		long deadline;
		int priority;
		int nbProc;
		IEnergyConsumptionProfile ecp = null;

		String type = params[0].toString();
		
		if("simple".equals(type)){
			firstRelease = Long.parseLong(params[1].toString());
			wcet = Long.parseLong(params[2].toString());
			wcee = Long.parseLong(params[3].toString());
			period = Long.parseLong(params[4].toString());
			deadline = Long.parseLong(params[5].toString());
			priority = Integer.parseInt(params[6].toString());
			ecp = params.length > 7
					&& params[7] != null ? ConsumptionProfileFactory
					.newIntance(params[7].toString())
					: ConsumptionProfileFactory.newIntance("default");
			iTask = new SimpleTask(firstRelease, wcet, wcee, period, deadline,
					priority, ecp);
			}

		else if("graph".equals(type)){

			firstRelease = Long.parseLong(params[1].toString());
			period = Long.parseLong(params[2].toString());
			deadline = Long.parseLong(params[3].toString());
			priority = Integer.parseInt(params[4].toString());
			@SuppressWarnings("unchecked")
			ArrayList<SubTask> subtasks = (ArrayList<SubTask>) params[5];

			ecp = params.length > 6 && params[6] != null ? ConsumptionProfileFactory
					.newIntance(params[6].toString())
					: ConsumptionProfileFactory.newIntance("default");
			wcee = 0;
			ecp = ConsumptionProfileFactory.newIntance("default");
			iTask = new GraphTask(firstRelease, wcee, period, deadline,
					priority, subtasks, ecp);
			}

		else if("subtask".equals(type)){
			firstRelease = Long.parseLong(params[1].toString());
			wcet = Long.parseLong(params[2].toString());
			wcee = Long.parseLong(params[3].toString());

			period = Long.parseLong(params[4].toString());
			deadline = Long.parseLong(params[5].toString());
			priority = Integer.parseInt(params[6].toString());
			
			ecp = params.length > 7 && params[7] != null ? ConsumptionProfileFactory
					.newIntance(params[7].toString())
					: ConsumptionProfileFactory.newIntance("default");
			//TODO check the usage of subtask		
			nbProc = params.length > 8 && params[8] != null ? Integer.parseInt(params[8].toString()) :1;
			//ecp = ConsumptionProfileFactory.newIntance("default");
			iTask = new SubTask(firstRelease, wcet, wcee, period, deadline,
					priority, nbProc, ecp);
			}

		else 
			throw new IllegalArgumentException(
					"SchedulableFactory : Task model (" + params[0]
							+ ") doesn't exist...");
		return iTask;
	}
}